/*
 *   This File is Part of CuteOgre Game Engine
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *	Copyright 2010 Alexandre Pires ( c.alexandre.pires@gmail.com )
 *  Created on: 2010/08/22
 */

#ifndef INPUTHANDLER_H_
#define INPUTHANDLER_H_

#include "IManager.h"
#include "Singleton.h"

#include <OIS/OISEvents.h>
#include <OIS/OISInputManager.h>
#include <OIS/OISMouse.h>
#include <OIS/OISKeyboard.h>
#include <OIS/OISJoyStick.h>

class InputManager :
		public IManager,
		public OIS::MouseListener,
		public OIS::KeyListener,
		public OIS::JoyStickListener,
		public Singleton<InputManager> {

public:
	enum KeyCode {
		KeyNone = 0x00, Escape = 0x01, One = 0x02, Two = 0x03, Three = 0x04,
		Four = 0x05, Five = 0x06, Six = 0x07, Seven = 0x08, Eight = 0x09,
		Nine = 0x0A, Zero = 0x0B, Minus = 0x0C, Equals = 0x0D,
		Backspace = 0x0E, Tab = 0x0F, Q = 0x10, W = 0x11, E = 0x12, R = 0x13,
		T = 0x14, Y = 0x15, U = 0x16, I = 0x17, O = 0x18, P = 0x19,
		LeftBracket = 0x1A, RightBracket = 0x1B, Return = 0x1C,
		LeftControl = 0x1D, A = 0x1E, S = 0x1F, D = 0x20, F = 0x21, G = 0x22,
		H = 0x23, J = 0x24, K = 0x25, L = 0x26, Semicolon = 0x27,
		Apostrophe = 0x28, Grave = 0x29, LeftShift = 0x2A, Backslash = 0x2B,
		Z = 0x2C, X = 0x2D, C = 0x2E, V = 0x2F, B = 0x30, N = 0x31, M = 0x32,
		Comma = 0x33, Period = 0x34, Slash = 0x35, RightShift = 0x36,
		Multiply = 0x37, LeftAlt = 0x38, Space = 0x39, Capital = 0x3A,
		F1 = 0x3B, F2 = 0x3C, F3 = 0x3D, F4 = 0x3E, F5 = 0x3F, F6 = 0x40,
		F7 = 0x41, F8 = 0x42, F9 = 0x43, F10 = 0x44, NumLock = 0x45,
		ScrollLock = 0x46, Numpad7 = 0x47, Numpad8 = 0x48, Numpad9 = 0x49,
		Subtract = 0x4A, Numpad4 = 0x4B, Numpad5 = 0x4C, Numpad6 = 0x4D,
		Add = 0x4E, Numpad1 = 0x4F, Numpad2 = 0x50, Numpad3 = 0x51,
		Numpad0 = 0x52, Decimal = 0x53, OEM_102 = 0x56, F11 = 0x57, F12 = 0x58,
		F13 = 0x64, F14 = 0x65, F15 = 0x66, Kana = 0x70, ABNT_C1 = 0x73,
		Convert = 0x79, NoConvert = 0x7B, Yen = 0x7D, ABNT_C2 = 0x7E,
		NumpadEquals = 0x8D, PrevTrack = 0x90, At = 0x91, Colon = 0x92,
		Underline = 0x93, Kanji = 0x94, Stop = 0x95, AX = 0x96,
		Unlabeled = 0x97, NextTrack = 0x99, NumpadEnter = 0x9C,
		RightControl = 0x9D, Mute = 0xA0, Calculator = 0xA1, PlayPause = 0xA2, /* Play / Pause */
		MediaStop = 0xA4, VolumeDown = 0xAE, VolumeUp = 0xB0, WebHome = 0xB2,
		NumpadComma = 0xB3, Divide = 0xB5, SysRq = 0xB7, RightAlt = 0xB8,
		Pause = 0xC5, Home = 0xC7, ArrowUp = 0xC8, PageUp = 0xC9,
		ArrowLeft = 0xCB, ArrowRight = 0xCD, End = 0xCF, ArrowDown = 0xD0,
		PageDown = 0xD1, Insert = 0xD2, Delete = 0xD3, LeftWindows = 0xDB,
		RightWindow = 0xDC, RightWindows = 0xDC, AppMenu = 0xDD, Power = 0xDE,
		Sleep = 0xDF, Wake = 0xE3, WebSearch = 0xE5, WebFavorites = 0xE6,
		WebRefresh = 0xE7, WebStop = 0xE8, WebForward = 0xE9, WebBack = 0xEA,
		MyComputer = 0xEB, Mail = 0xEC, MediaSelect = 0xED
	};

	enum MouseButton {
		Left = 0, Right, Middle, Button0 = 0, Button1, Button2, Button3,
		Button4, Button5, Button6, Button7, None = -1
	};

friend class GameEngine;

private:
	OIS::InputManager* mInputManager;
	OIS::Mouse* mMouse;
	OIS::Keyboard* mKeyboard;
	bool mShutdown;

protected:
	InputManager ( ) :
		mShutdown ( true ) {

	}

public:
	~InputManager () {
	}

	static InputManager* getSingletonPtr ( void ) {
		return ms_Singleton;
	}

	static InputManager& getSingleton ( void ) {
		assert( ms_Singleton );
		return ( *ms_Singleton );
	}

	void init ();
	void shutdown ();
	void updateEvents ();

	bool mouseMoved ( const OIS::MouseEvent &rEvt );
	bool mousePressed ( const OIS::MouseEvent &rEvt, OIS::MouseButtonID );
	bool mouseReleased ( const OIS::MouseEvent &rEvt, OIS::MouseButtonID );
	bool keyPressed ( const OIS::KeyEvent &rEvt );
	bool keyReleased ( const OIS::KeyEvent &rEvt );
	bool buttonPressed ( const OIS::JoyStickEvent &evt, int index );
	bool buttonReleased ( const OIS::JoyStickEvent &evt, int index );
	bool axisMoved ( const OIS::JoyStickEvent &evt, int index );
	bool povMoved ( const OIS::JoyStickEvent &evt, int index );

};

#endif /* InputManager_H_ */
